package code.util;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class HTTPUtil {
	
	/** HttpClient线程池 */
	private static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
	/** 默认的线程安全httpclient实例 */
	public static CloseableHttpClient defaultHttpClient = null;
	
	static {
		// Increase max total connection to 300
		cm.setMaxTotal(300);
		// Increase default max connection per route to 100
		cm.setDefaultMaxPerRoute(100);
		// 每隔指定ms检查一下线程池的http连接，防止某些连接在非活动的时候，处于半关闭状态
		cm.setValidateAfterInactivity(4000);
		
		RequestConfig defaultRequestConfig = RequestConfig.custom()
				  .setSocketTimeout(10000)
				  .setConnectTimeout(10000)
				  .setConnectionRequestTimeout(10000)
//				  .setStaleConnectionCheckEnabled(true)
				  .build();

//		HttpHost proxy = new HttpHost("127.0.0.1", 1080, "http");

		defaultHttpClient = HttpClients.custom()
                .setDefaultRequestConfig(defaultRequestConfig)
                .setConnectionManager(cm)
//				.setProxy(proxy)
                .build();
	}
	
	/**
	 * 发送Post请求
	 * @param url 网址
	 * @param content RequestBody内容
	 * @param contentCharset RequestBody的编码
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendPost(String url, String content, String contentCharset, String respCharset) {
		return sendPost(null, url, content, contentCharset, respCharset);
	}
	
	/**
	 * 发送Post请求
	 * @param url 网址
	 * @param content RequestBody内容
	 * @param reqCharset RequestBody的编码
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendPost(String url, String content, Charset reqCharset, Charset respCharset) {
		return sendPost(null, url, content, reqCharset, respCharset);
	}
	
	/**
	 * 发送Post请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param content RequestBody内容
	 * @param reqCharset RequestBody的编码
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendPost(HttpClient httpClient, String url, String content, String reqCharset, String respCharset) {

		Charset req_charset = null;
		if (Charset.isSupported(reqCharset)) {
			req_charset = Charset.forName(reqCharset);
		}
		Charset resp_charset = null;
		if (Charset.isSupported(respCharset)) {
			resp_charset = Charset.forName(respCharset);
		}
		
		return sendPost(httpClient, url, content, req_charset, resp_charset);
	}
	
	/**
	 * 发送Post请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param content RequestBody内容
	 * @param reqCharset RequestBody的编码
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendPost(HttpClient httpClient, String url, String content, Charset reqCharset, Charset respCharset) {

		StringEntity myEntity;
		if (reqCharset != null) {
			myEntity = new StringEntity(content, reqCharset);
		} else {
			myEntity = new StringEntity(content, StandardCharsets.UTF_8);
		}
		
		return sendPost(httpClient, url, myEntity, respCharset);
	}
	
	/**
	 * 发送Post请求
	 * @param url 网址
	 * @param entity RequestBody内容
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendPost(String url, HttpEntity entity, String respCharset) {
		Charset resp_charset = null;
		if (Charset.isSupported(respCharset)) {
			resp_charset = Charset.forName(respCharset);
		}
		return sendPost(null, url, entity, resp_charset);
	}
	
	/**
	 * 发送Post请求
	 * @param url 网址
	 * @param entity RequestBody内容
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendPost(String url, HttpEntity entity, Charset respCharset) {
		return sendPost(null, url, entity, respCharset);
	}
	
	/**
	 * 发送Post请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param entity RequestBody内容
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendPost(HttpClient httpClient, String url, HttpEntity entity, String respCharset) {
		Charset resp_charset = null;
		if (Charset.isSupported(respCharset)) {
			resp_charset = Charset.forName(respCharset);
		}
		return sendPost(httpClient, url, entity, resp_charset);
	}
	
	/**
	 * 发送Post请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param entity RequestBody内容
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendPost(HttpClient httpClient, String url, HttpEntity entity, Charset respCharset) {
		HttpResult httpResult = new HttpResult();
		
		HttpEntity resp_entity = null;
		try {
			if (httpClient == null) {
				httpClient = defaultHttpClient;
			}
			HttpPost post = new HttpPost(url);
			post.setEntity(entity);
			HttpResponse response = httpClient.execute(post);
			resp_entity = response.getEntity();
			
			// 设置返回值
			httpResult.setStatus_code(response.getStatusLine().getStatusCode());
			// 设置返回内容
			String resp_content = "";
			if (respCharset == null) {
				resp_content = EntityUtils.toString(resp_entity, StandardCharsets.UTF_8);
			} else {
				resp_content = EntityUtils.toString(resp_entity, respCharset);
			}
			httpResult.setContent(resp_content);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			EntityUtils.consumeQuietly(resp_entity);
		}
		return httpResult;
	}
	
	/**
	 * 发送Get请求
	 * @param url 网址
	 * @return Response的内容
	 */
	public static HttpResult sendGet(String url) {
		return sendGet(null, url, StandardCharsets.UTF_8);
	}

	/**
	 * 发送Get请求
	 * @param url 网址
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendGet(String url, String respCharset) {
		return sendGet(null, url, respCharset);
	}

	/**
	 * 发送Get请求
	 * @param url 网址
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendGet(String url, Charset respCharset) {
		return sendGet(null, url, respCharset);
	}
	
	/**
	 * 发送Get请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @return Response的内容
	 */
	public static HttpResult sendGet(HttpClient httpClient, String url) {
		return sendGet(httpClient, url, StandardCharsets.UTF_8);
	}
	
	/**
	 * 发送Get请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendGet(HttpClient httpClient, String url, String respCharset) {
		Charset resp_charset = null;
		if (Charset.isSupported(respCharset)) {
			resp_charset = Charset.forName(respCharset);
		}
		return sendGet(httpClient, url, resp_charset);
	}
	
	/**
	 * 发送Get请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendGet(HttpClient httpClient, String url, Charset respCharset) {
		HttpResult httpResult = new HttpResult();
		
		HttpEntity resp_entity = null;
		try {
			if (httpClient == null) {
				httpClient = defaultHttpClient;
			}
			HttpGet get = new HttpGet(url);
			
//			get.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
//			get.setHeader("Accept-Encoding", "gzip, deflate");
//			get.setHeader("Accept-Language", "zh-CN,zh;q=0.8,fr;q=0.6,zh-TW;q=0.4");
//			get.setHeader("Cache-Control", "no-cache");
//			get.setHeader("Connection", "keep-alive");
//			get.setHeader("Host", "www.ximalaya.com");
//			get.setHeader("Pragma", "no-cache");
//			get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");
			
			HttpResponse response = httpClient.execute(get);
			
			resp_entity = response.getEntity();
			
			// 设置返回值
			httpResult.setStatus_code(response.getStatusLine().getStatusCode());
			// 设置返回内容
			String resp_content = "";
			if (respCharset == null) {
				resp_content = EntityUtils.toString(resp_entity, StandardCharsets.UTF_8);
			} else {
				resp_content = EntityUtils.toString(resp_entity, respCharset);
			}
			httpResult.setContent(resp_content);
		} catch (Exception e) {
			System.out.println("url :" + url);
			e.printStackTrace();
		} finally {
			EntityUtils.consumeQuietly(resp_entity);
		}
		return httpResult;
	}

	/**
	 * 发送Get请求，返回流
	 * @param url 网址
	 * @return Response的流
	 */
	public static InputStream sendGetEntity(String url) {
		return sendGetEntity(null, url);
	}
	
	/**
	 * 发送Get请求，返回流
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @return Response的流
	 */
	public static InputStream sendGetEntity(HttpClient httpClient, String url) {
		InputStream answerRes = null;
		try {
			if (httpClient == null) {
				httpClient = defaultHttpClient;
			}
			HttpGet get = new HttpGet(url);
			HttpResponse response = httpClient.execute(get);

			if (response.getStatusLine().getStatusCode() == 200) {
				// 如果状态码为200,就是正常返回
				answerRes = response.getEntity().getContent();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return answerRes;
	}
	
	/**
	 * 发送Delete请求
	 * @param url 网址
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	@Deprecated
	public static HttpResult sendDelete(String url, String respCharset) {
		Charset resp_charset = null;
		if (Charset.isSupported(respCharset)) {
			resp_charset = Charset.forName(respCharset);
		}
		return sendDelete(null, url, resp_charset);
	}
	
	/**
	 * 发送Delete请求
	 * @param httpClient HttpClient实例
	 * @param url 网址
	 * @param respCharset ResponseBody的编码
	 * @return Response的内容
	 */
	public static HttpResult sendDelete(HttpClient httpClient, String url, Charset respCharset) {
		HttpResult httpResult = new HttpResult();
		
		HttpEntity resp_entity = null;
		try {
			if (httpClient == null) {
				httpClient = defaultHttpClient;
			}
			HttpDelete delete = new HttpDelete(url);
			HttpResponse response = httpClient.execute(delete);
			
			resp_entity = response.getEntity();
			
			// 设置返回值
			httpResult.setStatus_code(response.getStatusLine().getStatusCode());
			// 设置返回内容
			String resp_content = "";
			if (respCharset == null) {
				resp_content = EntityUtils.toString(resp_entity, StandardCharsets.UTF_8);
			} else {
				resp_content = EntityUtils.toString(resp_entity, respCharset);
			}
			httpResult.setContent(resp_content);
			
		} catch (Exception e) {
		} finally {
			EntityUtils.consumeQuietly(resp_entity);
		}
		return httpResult;
	}

}
